/**
 * @file KeyboardManager.h
 * @brief Keyboard manager component.
 *
 * Copyright 2009 Ryan Chew
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __DBL_KEYBOARDMANAGER_H_
#define __DBL_KEYBOARDMANAGER_H_

// Chewable Headers //
#include <cbl/Chewable.h>
#include <cbl/Core/Event.h>
#include <cbl/Core/GameComponent.h>
#include <cbl/Core/GameService.h>
#include <cbl/Core/GameTime.h>
#include <cbl/Util/Property.h>

// Delectable Headers //
#include "dbl/Delectable.h"
#include "dbl/Input/KeyCodes.h"
#include "dbl/Input/KeyboardEvents.h"
#include "dbl/Core/GameWindowEvents.h"

// External Dependencies //
#include <bitset>

namespace dbl
{
	// Using directive.
	using cbl::Event;

	//! @brief Keyboard management component.
	//! Register listeners with the keyboard manager events to respond to keyboard input.
	//! This class depends on a GameWindow service existing in the game application.
	class DBL_API KeyboardManager :
		public cbl::GameComponent
	{
	/***** Properties *****/
	public:
		//! Declare keyboard manager service type.
		CBL_GAMESERVICE_TYPE( KeyboardManager );

	/***** Events *****/
	public:
		Event< E::OnKeyDown >	OnKeyDown;	//!< Key down event (triggers as long as key is down).
		Event< E::OnKeyUp >		OnKeyUp;	//!< Key up event.
		Event< E::OnKeyClick >	OnKeyClick;	//!< Key clicked event (triggers once when key is pressed).
		Event< E::OnKeyChar >	OnKeyChar;	//!< Key character event.
	/***** Public Methods *****/
	public:
		//! Constructor.
		//! @param	game		Pointer to game.
		explicit KeyboardManager( cbl::Game & game );
		//! Destructor.
		virtual ~KeyboardManager();
		//! Pure virtual function to initialise component.
		virtual void Initialise( void );
		//! Pure virtual function to shut down component.
		virtual void Shutdown( void );
		//! Pure virtual update function (from IUpdatable).
		virtual void Update( const cbl::GameTime & time );

	/***** Event Handlers *****/
	public:
		//! Window key down event handler.
		DECL_EVENT_HANDLER( E::OnWindowKeyDown );
		//! Window key up event handler.
		DECL_EVENT_HANDLER( E::OnWindowKeyUp );
		//! Window key char event handler.
		DECL_EVENT_HANDLER( E::OnWindowKeyChar );
		//! Window lost focus event.
		DECL_EVENT_HANDLER( E::OnWindowLostFocus );
		
	/***** Private Types *****/
	private:
		//! Key list type.
		typedef std::bitset< Key::Count >	KeyList;

	/***** Private Members *****/
	private:
		KeyList				mKeys;		//!< Key state list.
		GameWindow			* mWindow;	//!< Game window to listen to input from.
	};
}

#endif // __DBL_KEYBOARDMANAGER_H_
